package mirrormonkey.core.server;

import mirrormonkey.core.server.MappingStackElement.FailMode;
import mirrormonkey.core.server.MappingStackElement.FindMode;
import mirrormonkey.framework.entity.SyncEntity;

public abstract class MappingStack {

	protected final ServerCoreModule module;

	protected final DummyMappingStackElement dummyElement;

	protected final SyncEntity entity;

	protected final ServerEntityData entityData;

	protected final ServerConnectionInfo connectionData;

	public MappingStack(ServerCoreModule module, SyncEntity entity,
			ServerEntityData entityData, ServerConnectionInfo connectionData) {
		this.module = module;
		this.dummyElement = new DummyMappingStackElement(this);
		this.entity = entity;
		this.entityData = entityData;
		this.connectionData = connectionData;
	}

	public abstract boolean exists();

	public abstract ExistingMappingStack create();

	public abstract MappingStack destroy();

	public boolean isEmpty() {
		System.out.println("MappingStack.isEmpty(): " + getTop());
		return !getTop().exists();
	}

	public MappingStackElement getTop() {
		System.out.println("ExistingMappingStack.getTop():\n  " + dummyElement
				+ "\n  " + dummyElement.prev + "\n  " + dummyElement.next
				+ "\n");
		return dummyElement.prev;
	}

	public MappingStackElement getBottom() {
		return dummyElement.next;
	}

	public MappingStackElement find(Class<? extends SyncEntity> connectedClass) {
		return find(connectedClass, FindMode.EXACT, FailMode.NONE);
	}

	public MappingStackElement find(Class<? extends SyncEntity> connectedClass,
			FindMode find, FailMode fail) {
		System.out.println("MappingStack.find(): "
				+ getTop().find(connectedClass, find, fail));
		return getTop().find(connectedClass, find, fail);
	}

}
